<template><div><h2 id="laravel-octane" tabindex="-1"><a class="header-anchor" href="#laravel-octane"><span>Laravel Octane</span></a></h2>
<ul>
<li><a href="#introduction">简介</a></li>
<li><a href="#installation">安装</a></li>
<li><a href="#server-prerequisites">服务器先决条件</a>
<ul>
<li><a href="#roadrunner">RoadRunner</a></li>
<li><a href="#swoole">Swoole</a></li>
</ul>
</li>
<li><a href="#serving-your-application">为应用程序提供服务</a>
<ul>
<li><a href="#serving-your-application-via-https">通过 HTTPS 服务应用程序</a></li>
<li><a href="#serving-your-application-via-nginx">通过 Nginx 提供服务</a></li>
<li><a href="#watching-for-file-changes">监听文件修改</a></li>
<li><a href="#specifying-the-worker-count">指定 Worker 数量</a></li>
<li><a href="#specifying-the-max-request-count">指定最大请求数量</a></li>
<li><a href="#reloading-the-workers">重载 Workers</a></li>
<li><a href="#stopping-the-server">停止服务</a></li>
</ul>
</li>
<li><a href="#dependency-injection-and-octane">依赖注入与 Octane</a>
<ul>
<li><a href="#container-injection">容器注入</a></li>
<li><a href="#request-injection">请求注入</a></li>
<li><a href="#configuration-repository-injection">配置文件注入</a></li>
</ul>
</li>
<li><a href="#managing-memory-leaks">管理内存泄漏</a></li>
<li><a href="#concurrent-tasks">并发任务</a></li>
<li><a href="#ticks-and-intervals">计时与间隔</a></li>
<li><a href="#the-octane-cache">Octane 缓存</a></li>
<li><a href="#tables">表</a></li>
</ul>
<h2 id="简介" tabindex="-1"><a class="header-anchor" href="#简介"><span>简介</span></a></h2>
<p><a href="https://github.com/laravel/octane" target="_blank" rel="noopener noreferrer">Laravel Octane</a> 通过使用高性能应用程序服务器为您的应用程序提供服务来增强您的应用程序的性能，包括 <a href="https://openswoole.com/" target="_blank" rel="noopener noreferrer">Open Swoole</a>，<a href="https://github.com/swoole/swoole-src" target="_blank" rel="noopener noreferrer">Swoole</a>【很遗憾它不支持协程】，和 <a href="https://roadrunner.dev/" target="_blank" rel="noopener noreferrer">RoadRunner</a>。Octane 启动您的应用程序一次，将其保存在内存中，然后以极快的速度向它提供请求。</p>
<h2 id="安装" tabindex="-1"><a class="header-anchor" href="#安装"><span>安装</span></a></h2>
<p>Octane 可以通过 Composer 包管理器安装：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line"><span class="token function">composer</span> require laravel/octane</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>安装 Octane 后，您可以执行 <code v-pre>octane:install</code> 命令，该命令会将 Octane 的配置文件安装到您的应用程序中：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan octane:install</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="服务器先决条件" tabindex="-1"><a class="header-anchor" href="#服务器先决条件"><span>服务器先决条件</span></a></h2>
<blockquote>
<p><strong>注意</strong><br>
Laravel Octane 需要 <a href="https://php.net/releases/" target="_blank" rel="noopener noreferrer">PHP 8.1+</a>.</p>
</blockquote>
<h3 id="roadrunner" tabindex="-1"><a class="header-anchor" href="#roadrunner"><span>RoadRunner</span></a></h3>
<p><a href="https://roadrunner.dev/" target="_blank" rel="noopener noreferrer">RoadRunner</a> 由使用 Go 构建的 RoadRunner 二进制文件提供支持。当您第一次启动基于 RoadRunner 的 Octane 服务器时，Octane 将为您提供下载和安装 RoadRunner 二进制文件。</p>
<h4 id="通过-laravel-sail-使用-roadrunner" tabindex="-1"><a class="header-anchor" href="#通过-laravel-sail-使用-roadrunner"><span>通过 Laravel Sail 使用 RoadRunner</span></a></h4>
<p>如果你打算使用 <a href="https://learnku.com/docs/laravel/10.x/sail" target="_blank" rel="noopener noreferrer">Laravel Sail</a> 开发应用，你应该运行如下命令安装 Octane 和 RoadRunner:</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">./vendor/bin/sail up</span>
<span class="line"></span>
<span class="line">./vendor/bin/sail <span class="token function">composer</span> require laravel/octane spiral/roadrunner</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>接下来，你应该启动一个 Sail Shell，并运行 <code v-pre>rr</code> 可执行文件检索基于 Linux 的最新版 RoadRunner 二进制文件：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">./vendor/bin/sail shell</span>
<span class="line"></span>
<span class="line"><span class="token comment"># Within the Sail shell...</span></span>
<span class="line">./vendor/bin/rr get-binary</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>安装完 RoadRunner 二进制文件后，你可以退出 Sail Shell 会话。然后，需要调整 Sail 用来保持应用运行的 <code v-pre>supervisor.conf</code> 文件。首先，请执行 <code v-pre>sail:publish</code> Artisan 命令：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">./vendor/bin/sail artisan sail:publish</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>接着，更新应用 <code v-pre>docker/supervisord.confd</code> 文件中的 <code v-pre>command</code> 指令，这样 Sail 就可以使用 Octane 作为服务器，而非 PHP 开发服务器，运行服务了：</p>
<div class="language-ini line-numbers-mode" data-highlighter="prismjs" data-ext="ini" data-title="ini"><pre v-pre class="language-ini"><code><span class="line"><span class="token key attr-name">command</span><span class="token punctuation">=</span><span class="token value attr-value">/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=roadrunner --host=0.0.0.0 --rpc-port=6001 --port=80</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>最后，请确保 <code v-pre>rr</code> 二进制文件是可执行的并重新构建 Sail 镜像：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line"><span class="token function">chmod</span> +x ./rr</span>
<span class="line"></span>
<span class="line">./vendor/bin/sail build --no-cache</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="swoole" tabindex="-1"><a class="header-anchor" href="#swoole"><span>Swoole</span></a></h3>
<p>如果你打算使用 Swoole 服务器来运行 Laravel Octane 应用，你必须安装 Swoole PHP 组件。通常可以通过 PECL 安装：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">pecl <span class="token function">install</span> swoole</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="open-swoole" tabindex="-1"><a class="header-anchor" href="#open-swoole"><span>Open Swoole</span></a></h4>
<p>如果你想要使用 Open Swoole 服务器运行 Laravel Octane 应用，你必须安装 Open Swoole PHP 扩展。通常可以通过 PECL 完成安装：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">pecl <span class="token function">install</span> openswoole</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>通过 Open Swoole 使用 Laravel Octane，可以获得 Swoole 提供的相同功能，如并发任务，计时和间隔。</p>
<h4 id="通过-laravel-sail-使用-swoole" tabindex="-1"><a class="header-anchor" href="#通过-laravel-sail-使用-swoole"><span>通过 Laravel Sail 使用 Swoole</span></a></h4>
<blockquote>
<p><strong>注意</strong><br>
在通过 Sail 提供 Octane 应用程序之前，请确保你使用的是最新版本的 Laravel Sail 并在应用程序的根目录中执行 <code v-pre>./vendor/bin/sail build --no-cache</code>。</p>
</blockquote>
<p>你可以使用 Laravel 的官方 Docker 开发环境 <a href="https://learnku.com/docs/laravel/10.x/sail" target="_blank" rel="noopener noreferrer">Laravel Sail</a> 开发基于 Swoole 的 Octane 应用程序。 Laravel Sail 默认包含 Swoole 扩展。但是，你仍然需要调整 Sail 使用的 <code v-pre>supervisor.conf</code> 件以保持应用运行。首先，执行 <code v-pre>sail:publish</code> Artisan 命令：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">./vendor/bin/sail artisan sail:publish</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>接下来，更新应用程序的 <code v-pre>docker/supervisord.conf</code> 文件的 <code v-pre>command</code> 指令，使得 Sail 使用 Octane 替代 PHP 开发服务器：</p>
<div class="language-ini line-numbers-mode" data-highlighter="prismjs" data-ext="ini" data-title="ini"><pre v-pre class="language-ini"><code><span class="line"><span class="token key attr-name">command</span><span class="token punctuation">=</span><span class="token value attr-value">/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=swoole --host=0.0.0.0 --port=80</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>最后，构建你的 Sail 镜像：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">./vendor/bin/sail build --no-cache</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="swoole-配置" tabindex="-1"><a class="header-anchor" href="#swoole-配置"><span>Swoole 配置</span></a></h4>
<p>Swoole 支持一些额外的配置选项，如果需要，你可以将它们添加到你的 <code v-pre>octane</code> 配置文件中。因为它们很少需要修改，所以这些选项不包含在默认配置文件中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'swoole'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'options'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'log_file'</span> <span class="token operator">=></span> <span class="token function">storage_path</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'logs/swoole_http.log'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'package_max_length'</span> <span class="token operator">=></span> <span class="token number">10</span> <span class="token operator">*</span> <span class="token number">1024</span> <span class="token operator">*</span> <span class="token number">1024</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="为应用程序提供服务" tabindex="-1"><a class="header-anchor" href="#为应用程序提供服务"><span>为应用程序提供服务</span></a></h2>
<p>Octane 服务器可以通过 <code v-pre>octane:start</code> Artisan 命令启动。此命令将使用由应用程序的 <code v-pre>octane</code> 配置文件的 <code v-pre>server</code> 配置选项指定的服务器：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan octane:start</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>默认情况下，Octane 将在 8000 端口上启动服务器（可配置），因此你可以在 Web 浏览器中通过 <code v-pre>http://localhost:8000</code> 访问你的应用程序。</p>
<h3 id="通过-https-为应用程序提供服务" tabindex="-1"><a class="header-anchor" href="#通过-https-为应用程序提供服务"><span>通过 HTTPS 为应用程序提供服务</span></a></h3>
<p>默认情况下，通过 Octane 运行的应用程序会生成以 <code v-pre>http://</code> 为前缀的链接。当使用 HTTPS 时，可将在应用的 <code v-pre>config/octane.php</code> 配置文件中使用的 <code v-pre>OCTANE_HTTPS</code> 环境变量设置为 <code v-pre>true</code>。当此配置值设置为 <code v-pre>true</code> 时，Octane 将指示 Laravel 在所有生成的链接前加上 <code v-pre>https://</code>：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'https'</span> <span class="token operator">=></span> <span class="token function">env</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'OCTANE_HTTPS'</span><span class="token punctuation">,</span> <span class="token constant boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="通过-nginx-为应用提供服务" tabindex="-1"><a class="header-anchor" href="#通过-nginx-为应用提供服务"><span>通过 Nginx 为应用提供服务</span></a></h3>
<blockquote>
<p><strong>提示</strong><br>
如果你还没有准备好管理自己的服务器配置，或者不习惯配置运行健壮的 Laravel Octane 应用所需的所有各种服务，请查看 <a href="https://forge.laravel.com/" target="_blank" rel="noopener noreferrer">Laravel Forge</a>。</p>
</blockquote>
<p>在生产环境中，你应该在传统 Web 服务器（例如 Nginx 或 Apache）之后为 Octane 应用提供服务。 这样做将允许 Web 服务器为你的静态资源（例如图片和样式表）提供服务，并管理 SSL 证书。</p>
<p>在下面的 Nginx 配置示例文件中，Nginx 将向在端口 8000 上运行的 Octane 服务器提供站点的静态资源和代理请求：</p>
<div class="language-nginx line-numbers-mode" data-highlighter="prismjs" data-ext="nginx" data-title="nginx"><pre v-pre class="language-nginx"><code><span class="line"><span class="token directive"><span class="token keyword">map</span> <span class="token variable">$http_upgrade</span> <span class="token variable">$connection_upgrade</span></span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token directive"><span class="token keyword">default</span> upgrade</span><span class="token punctuation">;</span></span>
<span class="line">    ''      <span class="token directive"><span class="token keyword">close</span></span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line"><span class="token directive"><span class="token keyword">server</span></span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token directive"><span class="token keyword">listen</span> <span class="token number">80</span></span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token directive"><span class="token keyword">listen</span> [::]:80</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token directive"><span class="token keyword">server_name</span> domain.com</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token directive"><span class="token keyword">server_tokens</span> <span class="token boolean">off</span></span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token directive"><span class="token keyword">root</span> /home/forge/domain.com/public</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">index</span> index.php</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">charset</span> utf-8</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">location</span> /index.php</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">try_files</span> /not_exists @octane</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">location</span> /</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">try_files</span> <span class="token variable">$uri</span> <span class="token variable">$uri</span>/ @octane</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">location</span> = /favicon.ico</span> <span class="token punctuation">{</span> <span class="token directive"><span class="token keyword">access_log</span> <span class="token boolean">off</span></span><span class="token punctuation">;</span> <span class="token directive"><span class="token keyword">log_not_found</span> <span class="token boolean">off</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span></span>
<span class="line">    <span class="token directive"><span class="token keyword">location</span> = /robots.txt</span>  <span class="token punctuation">{</span> <span class="token directive"><span class="token keyword">access_log</span> <span class="token boolean">off</span></span><span class="token punctuation">;</span> <span class="token directive"><span class="token keyword">log_not_found</span> <span class="token boolean">off</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">access_log</span> <span class="token boolean">off</span></span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token directive"><span class="token keyword">error_log</span>  /var/log/nginx/domain.com-error.log error</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">error_page</span> <span class="token number">404</span> /index.php</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">location</span> @octane</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">set</span> <span class="token variable">$suffix</span> <span class="token string">""</span></span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token directive"><span class="token keyword">if</span> (<span class="token variable">$uri</span> = /index.php)</span> <span class="token punctuation">{</span></span>
<span class="line">            <span class="token directive"><span class="token keyword">set</span> <span class="token variable">$suffix</span> ?<span class="token variable">$query_string</span></span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">        <span class="token directive"><span class="token keyword">proxy_http_version</span> 1.1</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">proxy_set_header</span> Host <span class="token variable">$http_host</span></span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">proxy_set_header</span> Scheme <span class="token variable">$scheme</span></span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">proxy_set_header</span> SERVER_PORT <span class="token variable">$server_port</span></span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">proxy_set_header</span> REMOTE_ADDR <span class="token variable">$remote_addr</span></span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">proxy_set_header</span> X-Forwarded-For <span class="token variable">$proxy_add_x_forwarded_for</span></span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">proxy_set_header</span> Upgrade <span class="token variable">$http_upgrade</span></span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">proxy_set_header</span> Connection <span class="token variable">$connection_upgrade</span></span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token directive"><span class="token keyword">proxy_pass</span> http://127.0.0.1:8000<span class="token variable">$suffix</span></span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="监视文件更改" tabindex="-1"><a class="header-anchor" href="#监视文件更改"><span>监视文件更改</span></a></h3>
<p>由于 Octane 服务器启动时应用程序被加载到内存中一次，因此对应用程序文件的任何更改都不会在您刷新浏览器时反映出来。例如，添加到 <code v-pre>routes/web.php</code> 文件的路由定义在服务器重新启动之前不会反映出来。为了方便起见，你可以使用 <code v-pre>--watch</code> 标志指示 Octane 在应用程序中的任何文件更改时自动重新启动服务器：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan octane:start <span class="token parameter variable">--watch</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>在使用此功能之前，您应该确保在本地开发环境中安装了 <a href="https://nodejs.org/" target="_blank" rel="noopener noreferrer">Node</a>。此外，你还应该在项目中安装 <a href="https://github.com/paulmillr/chokidar" target="_blank" rel="noopener noreferrer">Chokidar</a> 文件监视库：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line"><span class="token function">npm</span> <span class="token function">install</span> --save-dev chokidar</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>你可以使用应用程序的 <code v-pre>config/octane.php</code> 配置文件中的 <code v-pre>watch</code> 配置选项来配置应该被监视的目录和文件。</p>
<h3 id="指定工作进程数" tabindex="-1"><a class="header-anchor" href="#指定工作进程数"><span>指定工作进程数</span></a></h3>
<p>默认情况下，Octane 会为机器提供的每个 CPU 核心启动一个应用程序请求工作进程。这些工作进程将用于在进入应用程序时服务传入的 HTTP 请求。你可以使用 <code v-pre>--workers</code> 选项手动指定要启动的工作进程数量，当调用 <code v-pre>octane:start</code> 命令时：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan octane:start <span class="token parameter variable">--workers</span><span class="token operator">=</span><span class="token number">4</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>如果你使用 Swoole 应用程序服务器，则还可以指定要启动的任务工作进程数量：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan octane:start <span class="token parameter variable">--workers</span><span class="token operator">=</span><span class="token number">4</span> --task-workers<span class="token operator">=</span><span class="token number">6</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="指定最大请求数量" tabindex="-1"><a class="header-anchor" href="#指定最大请求数量"><span>指定最大请求数量</span></a></h3>
<p>为了防止内存泄漏，Octane 在处理完 500 个请求后会优雅地重新启动任何 worker。要调整这个数字，你可以使用 <code v-pre>--max-requests</code> 选项：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan octane:start --max-requests<span class="token operator">=</span><span class="token number">250</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="重载-workers" tabindex="-1"><a class="header-anchor" href="#重载-workers"><span>重载 Workers</span></a></h3>
<p>你可以使用 <code v-pre>octane:reload</code> 命令优雅地重新启动 Octane 服务器的应用 workers。通常，这应该在部署后完成，以便将新部署的代码加载到内存中并用于为后续请求提供服务：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan octane:reload</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="停止服务器" tabindex="-1"><a class="header-anchor" href="#停止服务器"><span>停止服务器</span></a></h3>
<p>你可以使用 <code v-pre>octane:stop</code> Artisan 命令停止 Octane 服务器：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan octane:stop</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="检查服务器状态" tabindex="-1"><a class="header-anchor" href="#检查服务器状态"><span>检查服务器状态</span></a></h4>
<p>你可以使用 <code v-pre>octane:status</code> Artisan 命令检查 Octane 服务器的当前状态：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan octane:status</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="依赖注入和-octane" tabindex="-1"><a class="header-anchor" href="#依赖注入和-octane"><span>依赖注入和 Octane</span></a></h2>
<p>由于 Octane 只启动你的应用程序一次，并在服务请求时将其保留在内存中，所以在构建你的应用程序时，你应该考虑一些注意事项。例如，你的应用程序的服务提供者的 <code v-pre>register</code> 和 <code v-pre>boot</code> 方法将只在 request worker 最初启动时执行一次。在随后的请求中，将重用相同的应用程序实例。</p>
<p>鉴于这个机制，在将应用服务容器或请求注入任何对象的构造函数时应特别小心。这样一来，该对象在随后的请求中就可能有一个稳定版本的容器或请求。</p>
<p>Octane 会在两次请求之间自动处理重置任何第一方框架的状态。然而，Octane 并不总是知道如何重置由你的应用程序创建的全局状态。因此，你应该知道如何以一种对 Octane 友好的方式来构建你的应用程序。下面，我们将讨论在使用 Octane 时可能引起问题的最常见情况。</p>
<h3 id="容器注入" tabindex="-1"><a class="header-anchor" href="#容器注入"><span>容器注入</span></a></h3>
<p>通常来说，你应该避免将应用服务容器或 HTTP 请求实例注入到其他对象的构造函数中。例如，下面的绑定将整个应用服务容器注入到绑定为单例的对象中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Service</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Contracts<span class="token punctuation">\</span>Foundation<span class="token punctuation">\</span>Application</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * Register any application services.</span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">register</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">app</span><span class="token operator">-></span><span class="token function">singleton</span><span class="token punctuation">(</span><span class="token class-name static-context">Service</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Application</span> <span class="token variable">$app</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Service</span><span class="token punctuation">(</span><span class="token variable">$app</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在这个例子中，如果在应用程序引导过程中解析 <code v-pre>Service</code> 实例，容器将被注入到该服务中，并且该容器将在后续的请求中保留。这对于你的特定应用程序<strong>可能</strong>不是一个问题，但是它可能会导致容器意外地缺少后来在引导过程中添加的绑定或后续请求中添加的绑定。</p>
<p>为了解决这个问题，你可以停止将绑定注册为单例，或者你可以将一个容器解析器闭包注入到服务中，该闭包总是解析当前的容器实例：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Service</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Container<span class="token punctuation">\</span>Container</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Contracts<span class="token punctuation">\</span>Foundation<span class="token punctuation">\</span>Application</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">app</span><span class="token operator">-></span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token class-name static-context">Service</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Application</span> <span class="token variable">$app</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Service</span><span class="token punctuation">(</span><span class="token variable">$app</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">app</span><span class="token operator">-></span><span class="token function">singleton</span><span class="token punctuation">(</span><span class="token class-name static-context">Service</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Service</span><span class="token punctuation">(</span><span class="token keyword">fn</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token class-name static-context">Container</span><span class="token operator">::</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>全局的 <code v-pre>app</code> 辅助函数和 <code v-pre>Container::getInstance()</code> 方法将始终返回应用程序容器的最新版本。</p>
<h3 id="请求注入" tabindex="-1"><a class="header-anchor" href="#请求注入"><span>请求注入</span></a></h3>
<p>通常来说，你应该避免将应用服务容器或 HTTP 请求实例注入到其他对象的构造函数中。例如，下面的绑定将整个请求实例注入到绑定为单例的对象中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Service</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Contracts<span class="token punctuation">\</span>Foundation<span class="token punctuation">\</span>Application</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * Register any application services.</span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">register</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">app</span><span class="token operator">-></span><span class="token function">singleton</span><span class="token punctuation">(</span><span class="token class-name static-context">Service</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Application</span> <span class="token variable">$app</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Service</span><span class="token punctuation">(</span><span class="token variable">$app</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'request'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在这个例子中，如果在应用程序启动过程中解析 <code v-pre>Service</code> 实例，则会将 HTTP 请求注入到服务中，并且相同的请求将由 <code v-pre>Service</code> 实例保持在后续请求中。因此，所有标头、输入和查询字符串数据以及所有其他请求数据都将不正确。</p>
<p>为了解决这个问题，你可以停止将绑定注册为单例，或者你可以将请求解析器闭包注入到服务中，该闭包始终解析当前请求实例。或者，最推荐的方法是在运行时将对象所需的特定请求信息传递给对象的方法之一：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Service</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Contracts<span class="token punctuation">\</span>Foundation<span class="token punctuation">\</span>Application</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">app</span><span class="token operator">-></span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token class-name static-context">Service</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Application</span> <span class="token variable">$app</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Service</span><span class="token punctuation">(</span><span class="token variable">$app</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'request'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">app</span><span class="token operator">-></span><span class="token function">singleton</span><span class="token punctuation">(</span><span class="token class-name static-context">Service</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Application</span> <span class="token variable">$app</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Service</span><span class="token punctuation">(</span><span class="token keyword">fn</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token variable">$app</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'request'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// Or...</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$service</span><span class="token operator">-></span><span class="token function">method</span><span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token function">input</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'name'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>全局的 <code v-pre>request</code> 帮助函数将始终返回应用程序当前处理的请求，因此可以在应用程序中安全使用它。</p>
<blockquote>
<p><strong>警告</strong><br>
在控制器方法和路由闭包中类型提示 Illuminate\Http\Request 实例是可以接受的。</p>
</blockquote>
<h3 id="配置库注入" tabindex="-1"><a class="header-anchor" href="#配置库注入"><span>配置库注入</span></a></h3>
<p>一般来说，你应该避免将配置库实例注入到其他对象的构造函数中。例如，以下绑定将配置库注入到绑定为单例的对象中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Service</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Contracts<span class="token punctuation">\</span>Foundation<span class="token punctuation">\</span>Application</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * Register any application services.</span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">register</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">app</span><span class="token operator">-></span><span class="token function">singleton</span><span class="token punctuation">(</span><span class="token class-name static-context">Service</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Application</span> <span class="token variable">$app</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Service</span><span class="token punctuation">(</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token function">make</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'config'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在这个示例中，如果在请求之间的配置值更改了，那么这个服务将无法访问新的值，因为它依赖于原始存储库实例。</p>
<p>作为解决方法，你可以停止将绑定注册为单例，或者将配置存储库解析器闭包注入到类中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Service</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Container<span class="token punctuation">\</span>Container</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Contracts<span class="token punctuation">\</span>Foundation<span class="token punctuation">\</span>Application</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">app</span><span class="token operator">-></span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token class-name static-context">Service</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Application</span> <span class="token variable">$app</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Service</span><span class="token punctuation">(</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token function">make</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'config'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">app</span><span class="token operator">-></span><span class="token function">singleton</span><span class="token punctuation">(</span><span class="token class-name static-context">Service</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Service</span><span class="token punctuation">(</span><span class="token keyword">fn</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token class-name static-context">Container</span><span class="token operator">::</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">make</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'config'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>全局 <code v-pre>config</code> 将始终返回配置存储库的最新版本，因此在应用程序中使用是安全的。</p>
<h3 id="管理内存泄漏" tabindex="-1"><a class="header-anchor" href="#管理内存泄漏"><span>管理内存泄漏</span></a></h3>
<p>请记住，Octane 在请求之间保留应用程序，因此将数据添加到静态维护的数组中将导致内存泄漏。例如，以下控制器具有内存泄漏，因为对应用程序的每个请求将继续向静态的 <code v-pre>$data</code> 数组添加数据：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Service</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Request</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Str</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 处理传入的请求。</span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">index</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">Service</span><span class="token operator">::</span><span class="token variable">$data</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token class-name static-context">Str</span><span class="token operator">::</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token comment">// ...</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在构建应用程序时，你应特别注意避免创建此类内存泄漏。建议在本地开发期间监视应用程序的内存使用情况，以确保您不会在应用程序中引入新的内存泄漏。</p>
<h2 id="并发任务" tabindex="-1"><a class="header-anchor" href="#并发任务"><span>并发任务</span></a></h2>
<blockquote>
<p><strong>警告</strong><br>
此功能需要 <a href="#swoole">Swoole</a>。</p>
</blockquote>
<p>当使用 Swoole 时，你可以通过轻量级的后台任务并发执行操作。你可以使用 Octane 的 <code v-pre>concurrently</code> 方法实现此目的。你可以将此方法与 PHP 数组解构结合使用，以检索每个操作的结果：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Server</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Laravel<span class="token punctuation">\</span>Octane<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Octane</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token punctuation">[</span><span class="token variable">$users</span><span class="token punctuation">,</span> <span class="token variable">$servers</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token class-name static-context">Octane</span><span class="token operator">::</span><span class="token function">concurrently</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">    <span class="token keyword">fn</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token keyword">fn</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token class-name static-context">Server</span><span class="token operator">::</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>由 Octane 处理的并发任务利用 Swoole 的 「task workers」 并在与传入请求完全不同的进程中执行。可用于处理并发任务的工作程序的数量由 <code v-pre>octane:start</code> 命令的 <code v-pre>--task-workers</code> 指令确定：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan octane:start <span class="token parameter variable">--workers</span><span class="token operator">=</span><span class="token number">4</span> --task-workers<span class="token operator">=</span><span class="token number">6</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>在调用 <code v-pre>concurrently</code> 方法时，你应该不要提供超过 1024 个任务，因为 Swoole 任务系统强制执行此限制。</p>
<h2 id="刻度和间隔" tabindex="-1"><a class="header-anchor" href="#刻度和间隔"><span>刻度和间隔</span></a></h2>
<blockquote>
<p><strong>警告</strong><br>
此功能需要 <a href="#swoole">Swoole</a>.</p>
</blockquote>
<p>当使用 Swoole 时，你可以注册定期执行的 「tick」 操作。你可以通过 <code v-pre>tick</code> 方法注册 「tick」 回调函数。提供给 <code v-pre>tick</code> 方法的第一个参数应该是一个字符串，表示定时器的名称。第二个参数应该是在指定间隔内调用的可调用对象。</p>
<p>在此示例中，我们将注册一个闭包，每 10 秒调用一次。通常，<code v-pre>tick</code> 方法应该在你应用程序的任何服务提供程序的 <code v-pre>boot</code> 方法中调用：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Octane</span><span class="token operator">::</span><span class="token function">tick</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'simple-ticker'</span><span class="token punctuation">,</span> <span class="token keyword">fn</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">ray</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Ticking...'</span><span class="token punctuation">)</span><span class="token punctuation">)</span></span>
<span class="line">        <span class="token operator">-></span><span class="token function">seconds</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div></div></div><p>使用 <code v-pre>immediate</code> 方法，你可以指示 Octane 在 Octane 服务器初始启动时立即调用 tick 回调，并在 N 秒后每次调用：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Octane</span><span class="token operator">::</span><span class="token function">tick</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'simple-ticker'</span><span class="token punctuation">,</span> <span class="token keyword">fn</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">ray</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Ticking...'</span><span class="token punctuation">)</span><span class="token punctuation">)</span></span>
<span class="line">        <span class="token operator">-></span><span class="token function">seconds</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span></span>
<span class="line">        <span class="token operator">-></span><span class="token function">immediate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="octane-缓存" tabindex="-1"><a class="header-anchor" href="#octane-缓存"><span>Octane 缓存</span></a></h2>
<blockquote>
<p><strong>警告</strong><br>
此功能需要 <a href="#swoole">Swoole</a>.</p>
</blockquote>
<p>使用 Swoole 时，你可以利用 Octane 缓存驱动程序，该驱动程序提供每秒高达 200 万次的读写速度。因此，这个缓存驱动程序是需要从缓存层中获得极高读写速度的应用程序的绝佳选择。</p>
<p>该缓存驱动程序由 <a href="https://www.swoole.co.uk/docs/modules/swoole-table" target="_blank" rel="noopener noreferrer">Swoole tables</a> 驱动。缓存中的所有数据可供服务器上的所有工作进程访问。但是，当服务器重新启动时，缓存数据将被清除：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">store</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'octane'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'framework'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'Laravel'</span><span class="token punctuation">,</span> <span class="token number">30</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p><strong>注意</strong><br>
Octane 缓存中允许的最大条目数可以在您的应用程序的 octane 配置文件中定义。</p>
</blockquote>
<h3 id="缓存间隔" tabindex="-1"><a class="header-anchor" href="#缓存间隔"><span>缓存间隔</span></a></h3>
<p>除了 Laravel 缓存系统提供的典型方法外，Octane 缓存驱动程序还提供了基于间隔的缓存。这些缓存会在指定的间隔自动刷新，并应在一个应用程序服务提供程序的 <code v-pre>boot</code> 方法中注册。例如，以下缓存将每五秒刷新一次：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Str</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">store</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'octane'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">interval</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'random'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token class-name static-context">Str</span><span class="token operator">::</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token argument-name">seconds</span><span class="token punctuation">:</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="表格" tabindex="-1"><a class="header-anchor" href="#表格"><span>表格</span></a></h2>
<blockquote>
<p><strong>警告</strong><br>
此功能需要 <a href="#swoole">Swoole</a>.</p>
</blockquote>
<p>使用 Swoole 时，你可以定义和与自己的任意 <a href="https://www.swoole.co.uk/docs/modules/swoole-table" target="_blank" rel="noopener noreferrer">Swoole tables</a> 进行交互。Swoole tables 提供极高的性能吞吐量，并且可以通过服务器上的所有工作进程访问其中的数据。但是，当它们内部的数据在服务器重新启动时将被丢失。</p>
<p>表在应用 <code v-pre>octane</code> 配置文件 <code v-pre>tables</code> 数组配置中设定。最大运行 1000 行的示例表已经配置。像下面这样，字符串行支持的最大长度在列类型后面设置：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'tables'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'example:1000'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'string:1000'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'votes'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'int'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>通过 <code v-pre>Octane::table</code> 方法访问表：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Laravel<span class="token punctuation">\</span>Octane<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Octane</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Octane</span><span class="token operator">::</span><span class="token function">table</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'example'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'uuid'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'Nuno Maduro'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'votes'</span> <span class="token operator">=></span> <span class="token number">1000</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">return</span> <span class="token class-name static-context">Octane</span><span class="token operator">::</span><span class="token function">table</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'example'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'uuid'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p><strong>注意</strong><br>
Swoole table 支持的列类型有： <code v-pre>string</code> ，<code v-pre>int</code> 和 <code v-pre>float</code> 。</p>
</blockquote>
<blockquote>
<p>本译文仅用于学习和交流目的，转载请务必注明文章译者、出处、和本文链接<br>
我们的翻译工作遵照 <a href="https://learnku.com/docs/guide/cc4.0/6589" target="_blank" rel="noopener noreferrer">CC 协议</a>，如果我们的工作有侵犯到您的权益，请及时联系我们。</p>
</blockquote>
<hr>
<blockquote>
<p>原文地址：<a href="https://learnku.com/docs/laravel/10.x/octane/14909" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/10.x/oc...</a></p>
<p>译文地址：<a href="https://learnku.com/docs/laravel/10.x/octane/14909" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/10.x/oc...</a></p>
</blockquote>
</div></template>


